﻿#include  "main.h"

FileManager_t     RomManager;
GameConsole_t     GameConsole;
Display_t         Display;
AudioDac_t        AudioDac;
InputManager_t    InputManager;
PixelStruct       RgbFrame[ PPU_HORIZONTAL_RESOLUTION * PPU_VERTICAL_PAL_RESOLUTION ];


bool GameConsoleStarted = false;

void RomFileAcces( _in_ void * context, _out_ uint8_t* pData,  _in_ uint32_t offset, _in_ uint16_t bytesCnt )
{
    uint8_t* pSource = RomManager.GetDataPointer() + offset;

    for ( uint16_t i = 0; i != bytesCnt; i++ ) // Подгружаем bytesCnt байт из файла игры в картридж
    {
        *pData++ = *pSource++;
    }
}


void PresentFrame( _in_ void * context, uint8_t* pData, uint16_t len, uint16_t posInFrame )
{
    DisplayIn_t displayIn;
   
    uint8_t color;
    
    if( pData )
    {
        for ( uint16_t xVisible = 0; xVisible < PPU_HORIZONTAL_RESOLUTION; xVisible++ ) 
        {
            color = pData[ xVisible ];
			color &= ~0xC0;
			//color = 255 - color;

			RgbFrame[ posInFrame + xVisible ].Red   = PpuPalette[color].Red;
			RgbFrame[ posInFrame + xVisible ].Green = PpuPalette[color].Green;
			RgbFrame[ posInFrame + xVisible ].Blue  = PpuPalette[color].Blue;

        }
    }
    else
    {
        displayIn.pData          = RgbFrame;
        displayIn.xSize          = PPU_HORIZONTAL_RESOLUTION;
        displayIn.ySize          = PPU_VERTICAL_PAL_RESOLUTION;
        displayIn.bitPerPixel    = 24;
        displayIn.savePath       = NULL;//"got2.bmp";

        Display.Present(&displayIn);
    }
}

void AudioDacQueryFrame( _out_ void * context, _out_ int16_t* pData, _in_ uint16_t bytesCnt )
{
    GameConsole.GetAudioFrame( pData, bytesCnt );
}

void JoysticEvent( _in_ void * context, _in_ uint8_t joysticA, _in_ uint8_t joysticB )
{
    GameConsole.SetButtonJoysticA( joysticA );
    GameConsole.SetButtonJoysticB( joysticB );
}

void GameConsoleControl( _in_ void * pContext, _in_ ConsoleCommand_t command )
{
    uint8_t* pGameContext;

    switch( command )
    {
        case GAME_CONSOLE_RESET_CMD:
             GameConsole.Init();
            // GameConsole.Reset();

        break;

        case GAME_CONSOLE_LOAD_GAME_ROM_CMD:
            GameConsoleStarted = false;

           // RomManager.Unload();
            RomManager.SetDialogTitle( " Please Select ROM File " );
            RomManager.SetDialogFilter( "ROM images\0*.nes\0" );
            RomManager.BrowseAndLoad(); // Выбор и открытие файла игры
           
            GameConsole.Init();
          //  GameConsole.Reset();
            AudioDac.Init();

            GameConsoleStarted = true;
        break;

        case GAME_CONSOLE_SAVE_GAME_CMD:
            
            pGameContext = new uint8_t[ GAME_CONTEXT_SIZE ];
            GameConsole.SaveGameContext( pGameContext );

        break;

        case GAME_CONSOLE_LOAD_GAME_CMD:
            
        break;

        default:
        
        break;
    }
}

    
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) //For VS2012
{
    SDL_Event sdlEvent;
    uint32_t  msec;
    uint16_t  fps;
        
    GameConsole.PresentFrameCallBack = PresentFrame;
    GameConsole.RomFileAccesCallBack = RomFileAcces;
    GameConsole.SetAudioSamplingRate( AUDIO_DAC_SAMPLING_RATE );
   
    Display.Init( PPU_HORIZONTAL_RESOLUTION, PPU_VERTICAL_PAL_RESOLUTION);
    
    AudioDac.QueryFrameCallBack = AudioDacQueryFrame;
 
    InputManager.SetJoystickCallBack( JoysticEvent, NULL );
    InputManager.SetConsoleControlCallBack( GameConsoleControl, NULL );
    InputManager.Init();
    
    SDL_Init( SDL_INIT_TIMER );


  
    do
    {
        while( SDL_PollEvent( &sdlEvent ) )
        {
            InputManager.Run( &sdlEvent );
            if( SDL_VIDEORESIZE == sdlEvent.resize.type )
            {
                Display.Init( sdlEvent.resize.w, sdlEvent.resize.h);
            }
        }
                     
        msec = SDL_GetTicks();
        

        if( GameConsoleStarted )
        {
            GameConsole.Run( msec );
            fps = GameConsole.GetFramesPerSecond();
        }
        Display.Run();

        
        char cap[20];

        cap[0] = 'F';
        cap[1] = 'P';
        cap[2] = 'S';
        cap[3] = '=';
        
        cap[4] = 48 + fps%1000/100;
        cap[5] = 48 + fps%100/10;
        cap[6] = 48 + fps%10/1;
        cap[7] = 0;

        SDL_WM_SetCaption( cap, NULL );
        SDL_Delay(1);

    } while( SDL_QUIT != sdlEvent.quit.type );

    RomManager.Unload();

}